package com.github.tetrisgame.manager;

import com.github.tetrisgame.R;
import com.github.tetrisgame.model.Block;
import com.github.tetrisgame.ui.view.GameView;
import com.github.tetrisgame.ui.view.PreviewView;
import com.github.tetrisgame.utils.Music;

public class GameCenter {
    public static final GameCenter defaultCenter = new GameCenter();
    private GameView mGameView;
    private int level = 1;
    private PreviewView mPreviewView;
    private int score = 0;
    private int row = 20;
    private int column = 10;
    private int[][] boards;
    private boolean gameState = false;
    private Music music = Music.defaultMusic;
    public int getLevel(){
        return level;
    }
    public void resetLevel(){
        this.level = 1;
    }
    public void addLevel(){
        music.level_upMusic();
        this.level += 1;
    }
    public boolean getGameState(){
        return gameState;
    }
    public int getScore(){
        return score;
    }
    public void changeGameState(){
        gameState = !gameState;
    }
    public void setBoardSize(int row,int column){
        this.row = row;
        this.column = column;
        BlockManager.defaultManager.resetPosition(row,column);
        this.boards = new int[row][column];
        mGameView.refresh();
    }

    private GameCenter(){

    }


    public void bindView(PreviewView previewView, GameView gameView) {
        this.mGameView = gameView;
        this.mPreviewView = previewView;
    }
    public void start(){
        showNext();
    }
    public void moveLeft(){
        music.moveMusic();

        Block block = BlockManager.defaultManager.getCurrentBlock();
        block.setColumn(block.getColumn()-1);
        if (isCollision()){
            block.setColumn(block.getColumn()+1);
        }
        mGameView.refresh();
    }
    public void moveRight(){
        music.moveMusic();
        Block block = BlockManager.defaultManager.getCurrentBlock();
        block.setColumn(block.getColumn()+1);
        if (isCollision()){
            block.setColumn(block.getColumn()-1);
        }
        mGameView.refresh();
    }
    public void moveDown(){
        Block block = BlockManager.defaultManager.getCurrentBlock();
        block.setRow(block.getRow()+1);
        if (isCollision()){
            block.setRow(block.getRow()-1);
            mergeBlock();
            clearAction();
            showNext();
        }
        mGameView.refresh();
    }
    public void moveQuickDown(){
        music.fast_downMusic();
        for (int i = 0; i < row/2; i++) {
            moveDown();
        }
    }

    private void mergeBlock() {
        Block block = BlockManager.defaultManager.getCurrentBlock();
        int[][] shapes = block.getShape();
        for (int i = 0; i < shapes.length; i++) {
            for (int j = 0; j < shapes[0].length; j++) {
                if (shapes[i][j] != 0 && block.getRow() + i<boards.length && block.getColumn() + j <boards[0].length){
                    boards[block.getRow() + i][block.getColumn() + j] = shapes[i][j];
                }
            }
        }
    }

    public void rotate(){
        music.rotateMusic();
        Block block = BlockManager.defaultManager.getCurrentBlock();
        block.rotate();
        if (isCollision()){
            block.rotate();
            block.rotate();
            block.rotate();
        }
        mGameView.refresh();
    }
    private void showNext(){
        Block previewBlock = BlockManager.defaultManager.getPreviewBlock(0,column/2-1);
        mPreviewView.showBlock(previewBlock);
    }
    private boolean isCollision(){
        Block block = BlockManager.defaultManager.getCurrentBlock();
        int[][] boards = GameCenter.defaultCenter.boards;
        int[][] shapes = block.getShape();
        for (int i = 0; i < shapes.length; i++) {
            for (int j = 0; j < shapes[0].length; j++) {
                if (shapes[i][j] != 0){
                    if(block.getColumn()+j < 0 || block.getColumn()+j>=column || block.getRow() + i >= row)return true;
                    if(boards[block.getRow() + i][block.getColumn() + j] != 0)return true;
                }
            }
        }
        return false;
    }

    public int[][] getBoards() {
        return boards;
    }
    public void clearAction(){
        music.clearMusic();
        int[][] boards = GameCenter.defaultCenter.boards;
        for (int i = 0; i < boards.length; i++) {
            boolean canClear = true;
            for (int j = 0; j < boards[i].length; j++) {
                if(boards[i][j] == 0){
                    canClear = false;
                    break;
                }

            }
            if(canClear){
                score += column;
                int[] newRow = new int[boards[0].length];
                for (int j = i-1; j >= 0; j--) {
                    boards[j+1] = boards[j];
                }
                boards[0] = newRow;
            }
        }
    }

    public boolean isOver() {
        Block block = BlockManager.defaultManager.getPreviewBlock();
        int[][] boards = GameCenter.defaultCenter.boards;
        int[][] board = block.getShape();
        for (int i = 0; i < board.length; i++) {
            for (int j = block.getColumn(); j < board[0].length+block.getColumn(); j++) {
                if(board[i][j- block.getColumn()] != 0 && boards[i][j] != 0) {
                    music.GameOverMusic();
                    return true;
                }
            }
        }
        return false;
    }
    public boolean isWin(){
        if(score>=12)return true;
        return false;
    }

    public void clearBoards() {
        for (int i = 0; i < row; i++) {
            for (int j = 0; j < column; j++) {
                boards[i][j] = 0;
            }
        }
    }

    public void resetScore() {
        this.score = 0;
    }

}
